<!--
 * 多选框组
 * @作者: 陈老师儿~
 * @手机: 18560000860
 -->
<template>
    <view class="pure-checkbox-group" :class="classes" :style="styles">
        <slot></slot>
    </view>
</template>

<script>
    import { computed } from "vue";
    import props from "./props.js";
    export default {
        options: {
            // 将自定义节点设置成虚拟的
            // 头条、飞书：因为合并后丢失事件和 'provide/inject'
            // 京东：因为合并后不能合并外层 'class'
            // 百度：因为合并后会在控制台疯狂报警告
            // #ifndef MP-TOUTIAO || MP-LARK || MP-JD || MP-BAIDU
            virtualHost: true,
            // #endif

            // 组件样式隔离
            styleIsolation: "apply-shared",

            // 允许使用多个插槽
            multipleSlots: true,
        },
        props: props,
        emits: ["update:modelValue", "change", "asyncChange"],
        inject: {
            // Field 组件的 change 事件
            onFieldChange: {
                from: "onFieldChange",
                default: () => {
                    return () => {};
                },
            },
        },
        computed: {
            // classes
            classes() {
                const classes = [];
                return classes;
            },

            // styles
            styles() {
                const styles = [];
                return styles;
            },
        },
        watch: {
            // 监听 modelValue 的变化
            modelValue: {
                handler() {
                    // 如果值发生变化，并且表单字段验证时机为 change，则触发字段验证
                    this.onFieldChange();
                },
                deep: true,
            },
        },
        methods: {
            // 更新
            update(value) {
                // 开启异步控制
                if (this.async) {
                    // 设置了异步处理函数
                    if (typeof this.asyncFunc === "function") {
                        // 调用异步处理函数,得到返回值
                        const result = this.asyncFunc(value, this.isChecked(value));

                        // 异步处理函数返回值是个 Promise
                        if (result instanceof Promise) {
                            result
                                .then(() => {
                                    const values = this.updateValues(value);
                                    this.$emit("update:modelValue", values);
                                    this.$emit("change", values);
                                })
                                .catch(() => {});
                            return;
                        }

                        // 返回值是正常值
                        if (!!result) {
                            const values = this.updateValues(value);
                            this.$emit("update:modelValue", values);
                            this.$emit("change", values);
                        }
                        return;
                    }

                    // 未设置异步处理函数
                    this.$emit("asyncChange", value, this.isChecked(value));
                    return;
                }

                // 未开启异步控制
                const values = this.updateValues(value);
                this.$emit("update:modelValue", values);
                this.$emit("change", values);
            },

            // 处理值
            updateValues(value) {
                let values = this.modelValue;
                const index = values.indexOf(value);
                if (index === -1) {
                    values.push(value);
                } else {
                    values.splice(index, 1);
                }
                return values;
            },

            // 是否选中
            isChecked(value) {
                return this.modelValue.indexOf(value) !== -1;
            },
        },
        provide() {
            return {
                globalDisabledClass: computed(() => this.disabledClass),
                checkedValue: computed(() => this.modelValue),
                update: this.update,
            };
        },
    };
</script>

<style scoped>
    @import "./style.css";
</style>
